# Written by Mayank
# This program is used to first parse the circuit file to remove
# all the \n and just keep space as a delimiter between different
# integers which define the circuit.

ckt_file = {"adder": "adder_32bit", "aes": "AES-non-expanded", "sha1": "sha-1", "sha256": "sha-256"}

fname = ckt_file["adder"];

file = open("../emp-tool/circuits/files/"+fname+".txt", "r")

acc = ""

while True:
    curline = file.readline()
    #print(curline)
    if len(curline) is 0:
        break
    curline = curline[:-1]
    if len(curline) > 0:
        acc += curline + ' '

file.close()

# Slice on whitespaces
split_data = acc.split()
#print(split_data)

cppfile = open("parsed_circuitfile.cpp", "w")
cppfile.seek(0)
cppfile.truncate()

boilerplate = "#include \"parsed_circuitfile.h\"\n"

decl_counter = 0
declaration_full = ""
# num_gate
declaration_full = declaration_full + "const int ckt_num_gate = " + split_data[decl_counter] + ";\n"
decl_counter = decl_counter + 1
# num_wire
declaration_full = declaration_full + "const int ckt_num_wire = " + split_data[decl_counter] + ";\n"
decl_counter = decl_counter + 1
# n1
declaration_full = declaration_full + "const int ckt_n1 = " + split_data[decl_counter] + ";\n"
decl_counter = decl_counter + 1
# n2
declaration_full = declaration_full + "const int ckt_n2 = " + split_data[decl_counter] + ";\n"
decl_counter = decl_counter + 1
#n3
declaration_full = declaration_full + "const int ckt_n3 = " + split_data[decl_counter] + ";\n"
decl_counter = decl_counter + 1
# wire array
declaration_full = declaration_full + "__m128i* ckt_wires = new __m128i[ckt_num_wire];\n"
# gate array
declaration_full = declaration_full + "int ckt_gates[ckt_num_gate*4] = {"

num_gates = int(split_data[0])

for i in range(num_gates):
    cond_dir = int(split_data[decl_counter])
    decl_counter = decl_counter + 1
    if cond_dir == 2:
        decl_counter = decl_counter + 1
        declaration_full = declaration_full + split_data[decl_counter] + ", "
        decl_counter = decl_counter + 1
        declaration_full = declaration_full + split_data[decl_counter] + ", "
        decl_counter = decl_counter + 1
        declaration_full = declaration_full + split_data[decl_counter] + ", "
        decl_counter = decl_counter + 1
        if split_data[decl_counter][0] == 'A':
            decl_counter = decl_counter + 1
            if decl_counter == len(split_data):
                declaration_full = declaration_full + "0"
            else:
                declaration_full = declaration_full + "0, "
        elif split_data[decl_counter][0] == "X":
            decl_counter = decl_counter + 1
            if decl_counter == len(split_data):
                declaration_full = declaration_full + "1"
            else:
                declaration_full = declaration_full + "1, "
    elif cond_dir == 1:
        decl_counter = decl_counter + 1
        declaration_full = declaration_full + split_data[decl_counter] + ", "
        decl_counter = decl_counter + 1
        declaration_full = declaration_full + "0" + ", "
        declaration_full = declaration_full + split_data[decl_counter] + ", "
        decl_counter = decl_counter + 1
        decl_counter = decl_counter + 1
        if decl_counter == len(split_data):
            declaration_full = declaration_full + "2"
        else:
            declaration_full = declaration_full + "2, "



declaration_full = declaration_full + "};\n"

declaration = "extern const std::string circuit_string = \""
closedecl = "\";"
remarks = "\n/*File autogenerated by parse_circuitfile.py*/"
cppfile.write(boilerplate)
cppfile.write(declaration)
cppfile.write(closedecl)
cppfile.write("\n")
cppfile.write(declaration_full)
cppfile.write(remarks)
cppfile.close()

cppheader = open("parsed_circuitfile.h", "w");
cppheader.seek(0)
cppheader.truncate()
headerinfo = "#include <string>\n#include \"sgx_trts.h\"\n#include \"sgx_intrin.h\"\nextern const std::string circuit_string;\nextern const int ckt_num_gate;\nextern const int ckt_num_wire;\nextern const int ckt_n1;\nextern const int ckt_n2;\nextern const int ckt_n3;\nextern __m128i* ckt_wires;\nextern int ckt_gates[4*"+split_data[0]+"];\n"
cppheader.write(headerinfo)
cppheader.close()



print("Contents of the parsed circuitfile have been hardcoded into the cpp file parsed_circuitfile.cpp")

